package org.example.lys.utils;

import lombok.extern.slf4j.Slf4j;
import okhttp3.*;

import javax.net.ssl.*;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 百度人像分离 Http请求工具类
 *
 * @author Liuruizhi
 * @date 2021/8/4 下午3:50
 */
public class HttpUtil {
    /**
     * 普通Http连接
     */
    private static OkHttpClient OK_HTTP_CLIENT;
    /**
     * Https连接
     */
    private static OkHttpClient OK_HTTP_CLIENT_TRUST_ALL_HOST_VERIFIER;
    /**
     * Content-Type;encoding
     */
    public static final String CONTENT_TYPE_FORM_GBK = "application/x-www-form-urlencoded;charset=gbk";
    public static final String CONTENT_TYPE_FORM_UTF8 = "application/x-www-form-urlencoded;charset=utf-8";
    public static final String CONTENT_TYPE_JSON_UTF8 = "application/json;charset=utf-8";

    /**
     * post 请求
     *
     * @param url         请求地址
     * @param contentType 类似  application/x-www-form-urlencoded;charset=utf-8
     * @param param       参数 根据contentType不同传递不同的格式
     * @return 结果
     * @throws IOException io异常
     */
    public static String okPost(String url, String contentType, String param) throws IOException {
        RequestBody body = RequestBody.create(MediaType.parse(contentType), param);
        Request request = new Request.Builder().url(url).post(body).build();
        Response response = getInstance().newCall(request).execute();
        if (response.isSuccessful()) {
            return response.body().string();
        } else {
            throw new IOException("Unexpected code " + response);
        }
    }

    /**
     * 创建普通的okHttp
     *
     * @return OkHttpClient
     */
    public static OkHttpClient getInstance() {

        if (OK_HTTP_CLIENT == null) {
            synchronized (HttpUtil.class) {
                if (OK_HTTP_CLIENT == null) {
                    OkHttpClient.Builder builder = new OkHttpClient.Builder();
                    OK_HTTP_CLIENT = builder.connectTimeout(30, TimeUnit.SECONDS)
                            .readTimeout(30, TimeUnit.SECONDS).build();

                }
            }
        }
        return OK_HTTP_CLIENT;
    }

    /**
     * 创建信任所有证书的okHttp
     *
     * @return
     */
    public static OkHttpClient getTrustAllHostVerifierInstance() {

        if (OK_HTTP_CLIENT_TRUST_ALL_HOST_VERIFIER == null) {
            synchronized (HttpUtil.class) {
                if (OK_HTTP_CLIENT_TRUST_ALL_HOST_VERIFIER == null) {
                    OkHttpClient.Builder builder = new OkHttpClient.Builder();
                    builder.hostnameVerifier(new TrustAllCerts.TrustAllHostnameVerifier());
                    builder.sslSocketFactory(TrustAllCerts.sslSocketFactory(), TrustAllCerts.x509TrustManager);
                    OK_HTTP_CLIENT_TRUST_ALL_HOST_VERIFIER = builder.connectTimeout(10, TimeUnit.SECONDS)
                            .readTimeout(30, TimeUnit.SECONDS).build();

                }
            }
        }

        return OK_HTTP_CLIENT_TRUST_ALL_HOST_VERIFIER;
    }
    /**
     * 老方法
     *
     * @param requestUrl  地址
     * @param accessToken Token
     * @param params      参数
     * @return 报文字符串
     * @throws Exception 异常
     */
    public static String post(String requestUrl, String accessToken, String params)
            throws Exception {
        String contentType = "application/x-www-form-urlencoded";
        return HttpUtil.post(requestUrl, accessToken, contentType, params);
    }

    public static String post(String requestUrl, String accessToken, String contentType, String params)
            throws Exception {
        String encoding = "UTF-8";
        if (requestUrl.contains("nlp")) {
            encoding = "GBK";
        }
        return HttpUtil.post(requestUrl, accessToken, contentType, params, encoding);
    }

    public static String post(String requestUrl, String accessToken, String contentType, String params, String encoding)
            throws Exception {
        String url = requestUrl + "?access_token=" + accessToken;
        return HttpUtil.postGeneralUrl(url, contentType, params, encoding);
    }

    public static String postGeneralUrl(String generalUrl, String contentType, String params, String encoding)
            throws Exception {
        URL url = new URL(generalUrl);
        // 打开和URL之间的连接
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        // 设置通用的请求属性
        connection.setRequestProperty("Content-Type", contentType);
        connection.setRequestProperty("Connection", "Keep-Alive");
        connection.setUseCaches(false);
        connection.setDoOutput(true);
        connection.setDoInput(true);

        // 得到请求的输出流对象
        DataOutputStream out = new DataOutputStream(connection.getOutputStream());
        out.write(params.getBytes(encoding));
        out.flush();
        out.close();

        // 建立实际的连接
        connection.connect();
        // 获取所有响应头字段
        Map<String, List<String>> headers = connection.getHeaderFields();
        // 遍历所有的响应头字段
//        for (String key : headers.keySet()) {
//            System.err.println(key + "--->" + headers.get(key));
//        }
        // 定义 BufferedReader输入流来读取URL的响应
        BufferedReader in = null;
        in = new BufferedReader(
                new InputStreamReader(connection.getInputStream(), encoding));
        String result = "";
        String getLine;
        while ((getLine = in.readLine()) != null) {
            result += getLine;
        }
        in.close();
        System.err.println("result:" + result);
        return result;
    }
}



/**
 * 忽略https证书类
 */
@Slf4j
class TrustAllCerts {
    static SSLSocketFactory sslSocketFactory() {
        SSLSocketFactory factory = null;
        try {
            SSLContext context = SSLContext.getInstance("TLS");
            context.init(null, new TrustManager[]{x509TrustManager}, new SecureRandom());
            factory = context.getSocketFactory();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return factory;
    }

    static X509TrustManager x509TrustManager = new X509TrustManager() {
        @Override
        public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

        }

        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    };

    static class TrustAllHostnameVerifier implements HostnameVerifier {

        @Override
        public boolean verify(String hostname, SSLSession session) {
            log.warn("Warning:URL Host:{},vs:{}", hostname, session.getPeerHost());
            return true;
        }
    }
}

